﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using HiSport.Application.HiSportService.Bas.BasDtos;
using HiSport.Application.HiSportService.Bas.BasSiteTypeManagement.Dtos;
using HiSport.Application.HiSportService.Bas.BasVenuesManagement.Dtos;
using HiSport.Application.HiSportService.Bas.BasVenuesManagement.Service;
using HiSport.Core;
using HiSport.Core.Entity;
using HiSport.Core.Entity.HiSportEntity.Bas;
using HiSport.Core.Util;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System.ComponentModel;

namespace HiSport.Application.HiSportService.Bas.BasSiteTypeManagement.Service
{

    /// <summary>
    /// 场地类型
    /// </summary>
    //[ApiDescriptionSettings("基础资料", Tag = "场地类型", SplitCamelCase = false)]
    [ApiDescriptionSettings("VenueSetup", Tag = "SiteType", SplitCamelCase = false)]
    public class BasSiteTypeService : ITransient, IBasSiteTypeService, IDynamicApiController
    {

        private readonly SqlSugarRepository<BasSiteType> _basSiteTypeRep;
        private readonly SqlSugarRepository<SysOrg> _sysOrgRep;
        private readonly SqlSugarRepository<BasSportsEventsType> _sportEventsTypeRep;
        /// <summary>
        /// 场地
        /// </summary>
        private readonly SqlSugarRepository<BasSite> _basSiteRep;
        private readonly SqlSugarRepository<BasVenues> _basVenuesRep;
        private readonly IBasVenuesService _basVenuesService;

        public BasSiteTypeService(SqlSugarRepository<BasSiteType> basSiteTypeRep,
            SqlSugarRepository<SysOrg> sysOrgRep,
            SqlSugarRepository<BasSportsEventsType> sportEventsTypeRep,
            SqlSugarRepository<BasSite> basSiteRep,
            SqlSugarRepository<BasVenues> basVenuesRep,
            IBasVenuesService basVenuesService)
        {
            _basSiteTypeRep = basSiteTypeRep;
            _sysOrgRep = sysOrgRep;
            _sportEventsTypeRep = sportEventsTypeRep;
            _basSiteRep = basSiteRep;
            _basVenuesRep = basVenuesRep;
        }

        /// <summary>
        /// 创建场地类型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>       
        [ApiDescriptionSettings(Name = "Create"), HttpPost]
        [DisplayName("创建场地类型")]
        public async Task<long> Create(BasSiteTypeCreateUpdateInputDto input)
        {
            #region 验证参数

            await CheckParam(input);

            #endregion

            #region 业务逻辑验证
          
            //每一个机构场地类型名称不能重复
            var isAnyName = await _basSiteTypeRep.IsAnyAsync(a => a.SiteTypeName == input.SiteTypeName&&a.VenueId==input.VenueId);
            if (isAnyName)
            {
                throw Oops.Oh("名称重复");
            }

            #endregion

            #region 保存           
            input.Id = 0;//创建的时候ID必须=0
            var data= input.Adapt<BasSiteType>();
            //获取场馆
            var venue =await _basVenuesRep.GetFirstAsync(a => a.IsDelete == false && a.Id == input.VenueId);
            data.CreateOrgId = venue.CreateOrgId;
            data.VenueName= venue.VenuesName;
            var newOrg = await _basSiteTypeRep.AsInsertable(data).ExecuteReturnEntityAsync();
            return newOrg.Id;
            #endregion
        }


        /// <summary>
        /// 修改场地类型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>       
        [ApiDescriptionSettings(Name = "Update")]
        [DisplayName("修改场地类型")]
        public async Task Update(BasSiteTypeCreateUpdateInputDto input)
        {
            #region 验证参数

            await CheckParam(input);

            #endregion

            #region 业务逻辑验证

            //是否存在当前ID的场地类型
            var id = input.Id;
            var data = await GetSiteType(id);

            //每一个机构场地类型名称不能重复
            var isAnyName = await _basSiteTypeRep.IsAnyAsync(a => a.SiteTypeName == input.SiteTypeName && a.Id != id && a.VenueId == input.VenueId);
            if (isAnyName)
            {
                throw Oops.Oh("名称重复");
            }

            #endregion

            #region 修改     

            //获取场馆
            var venue = await _basVenuesRep.GetFirstAsync(a => a.IsDelete == false && a.Id == input.VenueId);
            var updateData = input.Adapt<BasSiteType>();
            updateData.CreateOrgId= venue.CreateOrgId;
            updateData.VenueName = venue.VenuesName;
            await _basSiteTypeRep.AsUpdateable(updateData).IgnoreColumns(true).ExecuteCommandAsync();

            //修改组织
                _basVenuesRep.Context.Updateable<object>()
             .AS("BasSiteType")
             .SetColumns("CreateOrgId", venue.CreateOrgId)
             .Where($"id={input.Id}").ExecuteCommand();
            #endregion

        }


        /// <summary>
        /// 查询单个场地类型
        /// </summary>
        /// <param name="id">场地类型ID</param>
        /// <returns></returns>       
        [ApiDescriptionSettings(Name = "Get"), HttpGet]
        [DisplayName("查询单个场地类型")]
        public async Task<BasSiteTypeBasicDto> Get(long id)
        {
            var data = await GetSiteType(id);
            var result = data.Adapt<BasSiteTypeBasicDto>();

            //映射
            await SiteTypeMap(new List<BasSiteTypeBasicDto> { result });

            return result;

        }

        /// <summary>
        /// 查询场地类型列表 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>       
        [ApiDescriptionSettings(Name = "GetListPage"), HttpPost]
        [DisplayName("查询场地类型列表")]
        public async Task<SqlSugarPagedList<BasSiteTypeBasicDto>> GetListPage(BasSiteTypeInputDto input)
        {
            ParamNull(input);
            var data = SqlWhere(input);
            if (data == null) return new SqlSugarPagedList<BasSiteTypeBasicDto>();

            //排序 分页
            var result = await data.OrderBuilder(input)
                .Select(x => new BasSiteTypeBasicDto()
                {
                    Id = x.Id.SelectAll(),
                })
                .ToPagedListAsync(input.Page, input.PageSize);

            //冗余字段赋值
            await SiteTypeMap(result.Items.ToList());

            return result;
        }


        /// <summary>
        /// 获取场地类型列表
        /// </summary>
        /// <returns></returns>
        [ApiDescriptionSettings(Name = "GetListPage"), HttpGet]
        [DisplayName("获取场地类型列表")]
        public async Task<List<BasSiteTypeBasicDto>> GetSiteTypeList(long? venueId)
        {
            
            var res=await _basSiteTypeRep.AsQueryable()
                .WhereIF(venueId.HasValue,x=>x.VenueId==venueId)
                .Select(x=>new BasSiteTypeBasicDto()
                {
                    Id=x.Id.SelectAll(),
                })
                .ToListAsync();

            return res;
        }

        /// <summary>
        /// 删除场地类型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [UnitOfWork]
        [ApiDescriptionSettings(Name = "Delete"), HttpDelete]
        [DisplayName("删除场地类型")]
        public async Task Delete(DeleteInputDto input)
        {
            ParamNull(input);

            //是否存在当前ID的场地类型
            var id = input.Id;
            var data = await GetSiteType(id);

            var isAny = _basSiteRep.IsAny(a => a.SiteTypeId == id);
            if (isAny)
            {
                throw Oops.Oh("此场地类型已被场地引用，不可删除");
            }

            await _basSiteTypeRep.FakeDeleteAsync(data);

        }



        #region 其余私有方法

        /// <summary>
        /// 查询场地类型
        /// </summary>
        private async Task<BasSiteType> GetSiteType(long id)
        {
            //是否存在当前ID的场地类型

            var data = await _basSiteTypeRep.GetFirstAsync(a => a.IsDelete == false && a.Id == id);
            if (data == null)
            {
                throw Oops.Oh("未查询到当前场地类型数据");
            }
            return data;
        }

        /// <summary>
        /// 验证参数
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private async Task CheckParam(BasSiteTypeCreateUpdateInputDto input)
        {

            #region 验证参数

            if (input == null) throw Oops.Oh("参数错误:参数为NULL");

            var siteName = input.SiteTypeName;
            if (string.IsNullOrWhiteSpace(siteName))
            {
                throw Oops.Oh("参数错误:场地类型名称不能为空");
            }


            //运动类型是字典值：不能是非字典的值
            var sportsEventsTypeCode = input.SportsEventsTypeCode;
            if (string.IsNullOrWhiteSpace(sportsEventsTypeCode)) throw Oops.Oh($"参数有误:运动类型必填");

            #endregion


        }

        /// <summary>
        /// 查询列表Where条件拼装
        /// 要验证返回NULL的情况
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<BasSiteType> SqlWhere(BasSiteTypeInputDto input)
        {
            if (input == null) throw Oops.Oh("参数有误:参数为NULL");
            var data = _basSiteTypeRep.AsQueryable();

            data = data.Where(a => a.IsDelete == false);

            #region 机构
            var orgIds = input.OrgIds;
            if (!orgIds.IsNullOrEmpty() && orgIds.Any())
            {
                data = data.Where(a => orgIds.Contains(a.CreateOrgId.Value));
            }
            #endregion

            #region 场地名称-模糊查询
            var siteTypeName = input.SiteTypeName;
            if (!string.IsNullOrWhiteSpace(siteTypeName))
            {
                data = data.Where(a => a.SiteTypeName.Contains(siteTypeName));
            }
            #endregion

            #region 运动类型Code
            var sportsEventsTypeCodeList = input.SportsEventsTypeCodeList;
            if (sportsEventsTypeCodeList != null && sportsEventsTypeCodeList.Any())
            {
                data = data.Where(a => sportsEventsTypeCodeList.Contains(a.SportsEventsTypeCode));
            }
            #endregion

            return data;
        }

        /// <summary>
        /// 冗余字段赋值
        /// </summary>
        /// <returns></returns>
        private async Task SiteTypeMap(List<BasSiteTypeBasicDto> input)
        {
            if (input.IsNullOrEmpty()) return;

            //运动类型          
            var sportsEventsTypeCodes = input.Select(a => a.SportsEventsTypeCode).Distinct().ToList();
            var sportTypeList = _sportEventsTypeRep.AsQueryable().Where(a => a.IsDelete == false && sportsEventsTypeCodes.Contains(a.SportsEventsCode)).Select(a => new
            {
                a.SportsEventsCode,
                a.SportsEventsName
            }).ToList();

            foreach (var item in input)
            {
                //运动类型名称
                var curType = sportTypeList.FirstOrDefault(a => a.SportsEventsCode.Equals(item.SportsEventsTypeCode, StringComparison.OrdinalIgnoreCase));
                if (curType != null) item.SportsEventsTypeTValue = curType.SportsEventsName;

            }

        }

        /// <summary>
        /// 参数为NULL验证
        /// </summary>
        /// <param name="input"></param>
        private void ParamNull(object input)
        {
            if (input == null) throw Oops.Oh("参数错误:参数为NULL");
        }

        #endregion

    }


}
